﻿using System;
using System.Collections.Generic;
using System.Web;
using System.Threading;

/// <summary>
/// Summary description for AsnyHandler
/// </summary>
public class AsnyHandler:IHttpAsyncHandler
{
    private void ProcessRequestCallback(object state)
    {
        AsyncResult async = (AsyncResult)state;
        // this is where the real work is done
        Thread.Sleep(10000);
        ProcessRequest(async.context);
        async._IsCompleted = true;
        if (null != async.cb)
            async.cb(async);
    }
    public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback asyncCallback, object state)
    {
        AsyncResult async = new AsyncResult(context, asyncCallback, state);
        // if the callback is null, we can return immediately and let EndProcessRequest do all the job
        // if callback is not null, we will use our thread pool to execute the necessary asynchronous operations
        // what happens in ASP.NET is that the callback in NOT null, so QueueUserWorkItem will be used
        if (null != async.cb)
            ThreadPool.QueueUserWorkItem(ProcessRequestCallback, async);
        return async;
    }
    // this design also satisfies method 4), we implement it this way to follow the Asynchronous Pattern as much as we can
    public void EndProcessRequest(IAsyncResult result)
    {
        AsyncResult async = (AsyncResult)result;
        if (null == async.cb)
            ProcessRequest(async.context);
    }

    public void ProcessRequest(HttpContext context)
    {
        context.Response.Write("<H1>This is an HttpHandler Test.</H1>");
        context.Response.Write("<p>Your Browser:</p>");
        context.Response.Write("Type: " + context.Request.Browser.Type + "<br>");
        context.Response.Write("Version: " + context.Request.Browser.Version);
    }
    public bool IsReusable
    {
        get { return true; }
    }
}
public class AsyncResult : IAsyncResult
{
    public bool _IsCompleted = false;
    public HttpContext context;
    public AsyncCallback cb;
    public object extraData;
    public AsyncResult(HttpContext context, AsyncCallback cb, object extraData)
    {
        this.context = context;
        this.cb = cb;
        this.extraData = extraData;
    }
    private string _content;
    public string Content { 
        get {return _content;}
        set{_content=value;} 
    }

    #region IAsyncResult接口
    public object AsyncState
    {
        get { return null; }
    }

    public System.Threading.WaitHandle AsyncWaitHandle
    {
        get { return null; }
    }

    public bool CompletedSynchronously
    {
        get { return false; }
    }
    public bool IsCompleted
    {
        get { return _IsCompleted; }
    }
    #endregion
}
